#include #include #include #include #include // This function reads the currently selected waveform and returns // it as an array of doubles. double* ReadWaveform(ViSession vi, long* elements) { ViStatus status; float yoffset, ymult; ViChar buffer[256]; ViChar c; long count, i; double* ptr = NULL; unsigned char szBuff[256] = { 0,}; assert(elements != NULL); status = viSetAttribute(vi,VI_ATTR_WR_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS); status = viSetAttribute(vi,VI_ATTR_RD_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS); // Turn headers off, this makes parsing easier status = viPrintf(vi, "header off\n"); if (status < VI_SUCCESS) goto error; // Get record length value status = viQueryf(vi, "hor:reco?\n", "%ld", elements); if (status < VI_SUCCESS) goto error; // Make sure start, stop values for curve query match the full record length status = viPrintf(vi, "data:start 1;data:stop %d\n", *elements); if (status < VI_SUCCESS) goto error; // Get the yoffset to help calculate the vertical values. status = viQueryf(vi, "WFMOutpre:YOFF?\n", "%f", &yoffset); if (status < VI_SUCCESS) goto error; // Get the ymult to help calculate the vertical values. status = viQueryf(vi, "WFMOutpre:YMULT?\n", "%f", &ymult); if (status < VI_SUCCESS) goto error; // Request 8bit binary data on the curve query status = viPrintf(vi, "DATA:ENCDG RIBINARY;WIDTH 1\n"); if (status < VI_SUCCESS) goto error; // Request the curve status = viPrintf(vi, "CURVE?\n"); if (status < VI_SUCCESS) goto error; // Always flush if a viScanf follows a viPrintf or viBufWrite. status = viFlush(vi, VI_WRITE_BUF | VI_READ_BUF_DISCARD); if (status < VI_SUCCESS) goto error; // Get first char and validate status = viSetAttribute(vi,VI_ATTR_RD_BUF_OPER_MODE, VI_FLUSH_DISABLE); status = viScanf(vi, "%c", &c); if (status < VI_SUCCESS) goto error; assert(c == '#'); // Get width of element field. status = viScanf(vi, "%c", &c); if (status < VI_SUCCESS) goto error; assert(c >= '0' && c <= '9'); // Read element characters count = c - '0'; for (i = 0; i < count; i++) { status = viScanf(vi, "%c", &c); if (status < VI_SUCCESS) goto error; assert(c >= '0' && c <= '9'); } // Read waveform into allocated storage ptr = (double*) malloc(*elements*sizeof(double)); for (i = 0; i < *elements; i++) { status = viScanf(vi, "%c", &c); if (status < VI_SUCCESS) goto error; ptr[i] = (((double) c) - yoffset) * ymult; } status = viFlush(vi, VI_WRITE_BUF | VI_READ_BUF_DISCARD); if (status < VI_SUCCESS) goto error; return ptr; error: // Report error and clean up viStatusDesc(vi, status, buffer); fprintf(stderr, "failure: %s\n", buffer); if (ptr != NULL) free(ptr); return NULL; } // This program reads a waveform from a Tektronix // TDS scope and writes the floating point values to // stdout. int main(int argc, char* argv[]) { ViSession rm = VI_NULL, vi = VI_NULL; ViStatus status; ViChar buffer[256]; double* wfm = NULL; long elements, i; // Open a default Session status = viOpenDefaultRM(&rm); if (status < VI_SUCCESS) goto error; // Open the gpib device at primary address 1, gpib board 8 status = viOpen(rm, "GPIB8::1::INSTR", VI_NULL, VI_NULL, &vi); if (status < VI_SUCCESS) goto error; // Read waveform and write it to stdout wfm = ReadWaveform(vi, &elements); if (wfm != NULL) { for (i = 0; i < elements; i++) { printf("%f\n", wfm[i]); } } // Clean up if (wfm != NULL) free(wfm); viClose(vi); // Not needed, but makes things a bit more understandable viClose(rm); return 0; error: // Report error and clean up viStatusDesc(vi, status, buffer); fprintf(stderr, "failure: %s\n", buffer); if (rm != VI_NULL) viClose(rm); if (wfm != NULL) free(wfm); return 1; }